package net.sf.xoperator.ui;

import java.util.ArrayList;
import java.util.List;

import net.sf.xoperator.blackboard.ConfigurationAwareKnowledgeSource;
import net.sf.xoperator.blackboard.NoPlanBlackBoardControl;
import net.sf.xoperator.configuration.KSConfiguration;
import net.sf.xoperator.rdfxmpp.SPARQLQuery;
import net.sf.xoperator.ui.aiml.AliceBotExternal;
import net.sf.xoperator.ui.aiml.AliceBotFactory;
import net.sf.xoperator.ui.txt.Interactor;

import org.jivesoftware.smack.packet.Message;
import org.openbbs.blackboard.filter.KindOfFilter;
import org.openbbs.blackboard.ks.KSExecutionContext;

/**
 * This class decides to where an incoming message goes. Either to the command
 * line interface, the Interactor or to the template engine.
 * 
 * @author joerg
 * 
 */
public class UIDelegate extends ConfigurationAwareKnowledgeSource {
	
	
	
	public UIDelegate(Interactor interact, NoPlanBlackBoardControl control) {
		super();
		this.interact = interact;
		this.control = control;
	}

	private Interactor interact;

	private AliceBotExternal bot;
	
	private NoPlanBlackBoardControl control;
	

	@Override
	public void executeInternal(KSExecutionContext context) {
		// String response;
		Message message = (Message) context.blackboard().read(new KindOfFilter(Message.class));
		//checks if the interactor can handle this
		String messageBody = message.getBody().trim();

	
		
		if (this.interact!=null && this.interact.isInteraction(messageBody)) {
         for (Object obj : this.interact.performInteraction(messageBody)) {
            context.blackboard().write(obj);
         }
			
		} else if(this.bot!=null){
			String response = this.bot.respond(messageBody,context,control);
			//we check if the bot returned a non empty string, if he did, we have to assume that something was  already written into the blackboard, thus we don't have to care about it, as it was already done.
			if(response.trim().length()>0){
				context.blackboard().write(new StringMessage(response));
			}
		}

	}

	@Override
	public boolean isEnabledInternal(KSExecutionContext context) {
		boolean retval = context.blackboard().exists(new KindOfFilter(Message.class))
		&& !(context.blackboard().exists(
				new KindOfFilter(SPARQLQuery.class))||context.blackboard().exists(
                  new KindOfFilter(MessageToUser.class)));
		return retval;
	}

	@Override
	public void configure(KSConfiguration config) throws Exception {
		if (config instanceof UIAimlConfiguration) {
			UIAimlConfiguration aimlc = (UIAimlConfiguration) config;
			AliceBotFactory fac = new AliceBotFactory(aimlc.getPath());
			this.bot = fac.getAliceBot();
			
		}
		
	}

	@Override
	public List<Class<? extends KSConfiguration>> getConfigurationClasses() {
		List<Class<? extends KSConfiguration>> classes = new ArrayList<Class<? extends KSConfiguration>>();
		classes.add(UIAimlConfiguration.class);
		return classes;
	}



}
